package com.fubowen.reader.db.model

import androidx.annotation.IntDef
import com.fubowen.reader.R
import com.fubowen.reader.extension.toSizeString
import com.fubowen.reader.extension.toTimeString
import org.jsoup.nodes.Element
import java.io.File
import java.net.URL
import kotlin.math.ceil

data class Tree(
    val absolutePath: String,
    var name: String,
    var icon: Int = 0,
    @Type
    var type: Int = TYPE_FOLDER,
    val time: String = "",
    val size: String = "",
    val goto: Int = 0,
    val children: MutableList<Tree> = mutableListOf(),
    @Status
    var status: Int = STATUS_NOT_START,
    var isRead: Boolean = false,
    var isChecked: Boolean = false,
    var errMsg: String? = null,
    var progress: Int = 0,
) {
    @Synchronized
    fun updateProgress(progress: Float) {
        this.progress = ceil(progress).toInt()
    }

    companion object {
        const val STATUS_NOT_START = 0
        const val STATUS_WAITING = 1
        const val STATUS_RUNNING = 2
        const val STATUS_COMPLETED = 3
        const val STATUS_ERROR = 6
        const val STATUS_PAUSED = 4
        const val STATUS_SHOW_MENU = 5

        const val TYPE_FOLDER = 0
        const val TYPE_FILE = 1
        const val TYPE_URL = 2
    }

    @IntDef(STATUS_NOT_START, STATUS_WAITING, STATUS_RUNNING, STATUS_COMPLETED, STATUS_PAUSED, STATUS_SHOW_MENU, STATUS_ERROR)
    @Retention(AnnotationRetention.SOURCE)
    annotation class Status

    @IntDef(TYPE_FOLDER, TYPE_FILE, TYPE_URL)
    @Retention(AnnotationRetention.SOURCE)
    annotation class Type
}

fun File.toTreeItem() = Tree(
    absolutePath = this.absolutePath,
    name = this.name,
    icon = if (this.isDirectory) R.drawable.ic_folder_64dp else R.drawable.ic_txt_64dp,
    type = if (this.isDirectory) Tree.TYPE_FOLDER else Tree.TYPE_FILE,
    time = this.lastModified().toTimeString(),
    size = this.length().toSizeString(),
    goto = if (this.isDirectory) R.drawable.ic_right_24dp else R.drawable.ic_check_24dp,
)

fun Element.toTreeItem(): Tree {
    val href = this.attr("href")
    val result = runCatching { URL(URL(this.baseUri()), href).toExternalForm() }
    return Tree(
        absolutePath = result.getOrDefault(href),
        name = this.text(),
        icon = R.drawable.ic_txt_64dp,
        type = Tree.TYPE_URL,
        time = href,
        size = "",
        goto = R.drawable.ic_check_24dp
    )
}

